require "window.rb"
require "mouse.rb"
require "gui.rb"

module Menu

#A StaticScreen is a menu. It suspends the game and redirects all input to itself.
#StaticScreen is typically used through derivation, although it can be used otherwise.
#StaticScreen#start suspends the game and starts the menu. StaticScreen#end returns to the game.

class StaticScreen
  #Begin rerouting input to the static screen. DO NOT OVERRIDE THIS METHOD.
  def start 
    $window.setStatic(self)
    $window.deleteAllImages
    $window.cursor.forceVisible
    onStart
  end
  #Return control to the GameWindow. DO NOT OVERRIDE THIS METHOD.
  def end
    onEnd
    $window.setGame
    $window.deleteAllWidgets
    $window.createWidgets
    $window.deleteAllImages
    $window.cursor.unforceVisible
    onTerminate
  end
  #Equivalent to Gosu::Window#button_down
  def button_down(id)
    #do nothing by default
  end
  #Equivalent to Gosu::Window#button_down
  def button_up(id)
    #do nothing by default
  end
  #Equivalent to Gosu::Window#update
  def update
  end
  #Returns a reference to the window to which the static screen is associated.
  def window
    return $window
  end
  #This method is called when the static screen is initialized. It is ment to be overridden in derived classes.
  #This is a good place to preform tasks such as creating widgets.
  def onStart
  end
  #This method is called when the static screen is uninitialized. It is ment to be overridden in derived classes.
  #This is a good place to preform tasks such as stopping audio. Widgets are automatically destroyed on exit by the base class StaticScreen
  def onEnd
  end
  def onTerminate
  end
  #Equivalent to Gosu::Window#draw
  def draw
  end
end

class  MenuBase < StaticScreen
  def button_down(id)
    #if id == Gosu::Button::KbEscape
    #  close
    if id == Gosu::Button::MsLeft
      mouse($window.mouse_x,$window.mouse_y)
    end
  end
  def mouse(x,y)
    #does nothing by default
  end
end

class StartMenu < StaticScreen
  NewGameProc = Proc.new { |parent| 
    parent.end    
    RubyScript.new("data/campaign.rb").run
  }
  LoadGameProc = Proc.new { |parent|
    parent.end
    FadeScreen.new(LoadGameScreen.new, 10).start  
  }
  CreditsProc = Proc.new { |parent|
    parent.end
    FadeScreen.new(CreditsScreen.new("data/credits.ini"), 10).start  
  }
  ExitProc = Proc.new { |parent|
    $flog.info("Exit Cmd") {"Terminal: Widget Event(Exit < GenericButton)"}
    FadeScreen.new(nil, 5).start  
    $window.close
    exit
  }
  def onStart
    $window.setBackgroundImage("img/banners/bg.png")
    GenericButton.new("New Game",self,"img/gui/startmenu/newgame.png","img/gui/startmenu/newgameo.png","null.png",224,125,415,167,NewGameProc,0)
    GenericButton.new("Load Game",self,"img/gui/startmenu/loadgame.png","img/gui/startmenu/loadgameo.png","null.png",224,192,416,235,LoadGameProc,0)
    GenericButton.new("Credits",self,"img/gui/startmenu/credits.png","img/gui/startmenu/creditso.png","null.png",256,260,403,300,CreditsProc,0)
    GenericButton.new("Exit",self,"img/gui/startmenu/exit.png","img/gui/startmenu/exito.png","null.png",282,325,358,365,ExitProc,0)
   # TextBox.new("textbar1", 100, 100)
  end
end

class LoadScreen < StaticScreen
  attr_accessor :image, :level, :levelName
  def initialize(image,level=nil,levelname=nil)
    @font = Gosu::Font.new($window, Gosu::default_font_name, 45)
    @font2 = Gosu::Font.new($window, Gosu::default_font_name, 20)
    @image=image
    #@times=0
    @level=level
    @levelName=levelname
  end
  def onStart
    begin
      $window.setBackgroundImage(@image)
    rescue
      $window.setBackgroundImage("img/banners/loadscreen/default/"+@image)
    end
    $window.cursor.forceVisible(false)
  end
  def update
    #if $faded #kind of a hack, have to check if it works on all platforms later
      #@times+=1
   # else
    if $faded
      Environment::Map.load(level)
      sleep(3) unless $debug
      self.end
    end
  end
  def draw
    @font.draw(@levelName, 320.1-((@font.text_width(@levelName)/2).round), 380.1, ZOrder::Text, 1.0, 1.0, 0xffffff00)
    @font2.draw("Loading...", 320.1-((@font2.text_width("Loading...")/2).round), 380.1+@font.height+5, ZOrder::Text, 1.0, 1.0, 0xffffff00)
  end
  def onEnd
    $window.cursor.unforceVisible
    $window.cursor.visible=false
  end
  def onTerminate
    FadeScreen.new.start
    $window.cursor.unforceVisible
    $window.cursor.visible=false
  end
end

class CreditsScreen < StaticScreen
  def initialize(credits)
    credits=IniFile.new(credits)
    @groups={}
    credits.sections { |group|
      members=credits[group]
      next if group.upcase == "HEADER" or group.upcase == "FOOTER"
      newmems={}
      members.each { |mem_name, mem_role|
        newmems[mem_name.gsub("_"," ").strip]=mem_role.gsub("_"," ").strip
      } 
      @groups[group.gsub("_"," ").strip] = newmems
    }
    #website=credits["Footer"]["Website"]
    credits=nil
    groupsnew=Array.new(Array.new)
    @groups.each { |k,v| groupsnew[k.slice(0,2).to_i]=[k.slice(2,k.size-2), v]  }
    @groups=groupsnew
    groupsnew=nil
    name=""
    members=[]
    @text="Legend of Zelda\nThe Triforce United\n\nWW-P Collab\n\n\n"
    @groups.each { |kv|
      next if kv==nil
      name=kv[0]
      members=kv[1]
      if  name!=""
        @text+=(name+"\n"+("_"*name.size)+"\n")
      end
      members.each { |mem|
        @text+=mem[0]
        @text+=(" - "+mem[1]) if mem[1]!=nil and mem[1]!=""
        @text+="\n"
      }
      @text+="\n"
    }
    @groups=nil
    @image=Gosu::Image.from_text($window,@text,Gosu::default_font_name(),25,5,640,:center)
    @text=nil
    @drawcycle=0
  end
  def onStart
    @song=Gosu::Sample.new($window,"audio/credits/This_Valley_Rocks.wav").play
  end
  def onEnd
    @song.stop
  end
  def button_down(id)
    if id != Gosu::Button::MsLeft and id != Gosu::Button::MsRight
      self.end
      StartMenu.new.start
    end
  end
  def draw
    @image.draw(0.1,300.1-((@drawcycle/2).round),ZOrder::Text)
    @drawcycle+=1
  end
end

class FadeScreen < StaticScreen
  public
  attr_reader :widgetID
  def initialize(fadeTo=nil, speed=1)
    $faded=false
    @image=Gosu::Image.new($window, "img/banners/black.bmp", true)
    @fading=false
    @speed=speed
    @fadeTo=fadeTo
    @color=Gosu::Color.new(0xffffffff)
  end
  def fading?
    return @fading
  end
  def onStart
    @fading=true
    @alpha=0
  end
  def draw
    if @fading
      @alpha+=@speed
      if @alpha > 255
        @alpha=255
      end
      @color.alpha=@alpha
      @image.draw(0, 0, ZOrder::Top+1, 640, 480, @color)
      if @alpha == 255
        endFade
        @widgetID = FadeIn.new(@speed)
      end
    end
  end
  def endFade
    @fading=false
    @image=nil
    self.end
    @fadeTo.start if @fadeTo!=nil
  end
  
  class FadeIn < Widget
    def initialize(speed=5)
      @image=Gosu::Image.new($window, "img/banners/black.bmp", true)
      @speed=speed
      @color=Gosu::Color.new(0x00ffffff)
      @alpha=255
      super(Button::Image, 0, 0, 0, 0)
      wakeUp
      stickFocus
      $window.setFocus(nil)
    end
    def draw
      @alpha-=@speed
      if @alpha < 0
        @alpha=0
      end
      @color.alpha=@alpha
      @image.draw(0, 0, ZOrder::Top+1, 640, 480, @color)
      if @alpha == 0
        endFade
      end
    end
    def endFade
      unstickFocus
      $window.setFocus(nil)
      del
      $faded=true
    end
  end
  
end

class LoadGameScreen < StaticScreen
  ChooseProc=Proc.new{|file| $window.menu.textbox.text=file}
  SubmitProc=Proc.new{}
  attr_reader :selbox, :textbox
  def onStart
    #$window.newImage(70, -10, ZOrder::SceneOverlay, "img/gui/generic/menularge.png")
    $window.newImage(224, 10, ZOrder::Text, "img/gui/startmenu/loadgame.png")
    s=SelectionBox.new("savegame", 130, 70, ChooseProc)
    Dir.foreach("saves/") { |file|
      if File.file?("saves/"+file)
        s.newItem(file.gsub(".sav","").capitalize,file)
        puts "here"
      end
    }
    @selbox=s.id
    @textbox=TextBox.new("savegame", 220, 370)
    @button=ThemeButton.new("loadform_submit", "Load Game", 270, 415, SubmitProc)
  end
end

class SavedGameLoadScreen < StaticScreen
  attr_accessor :image, :level, :levelName
  def initialize(image,file=nil,levelname=nil)
    @font = Gosu::Font.new($window, Gosu::default_font_name, 45)
    @font2 = Gosu::Font.new($window, Gosu::default_font_name, 20)
    @image=image
    @file=nil
    @levelName=levelname
  end
  def onStart
    begin
      $window.setBackgroundImage(@image)
    rescue
      $window.setBackgroundImage("img/banners/loadscreen/default/"+@image)
    end
    $window.cursor.forceVisible(false)
  end
  def update
    if $faded
      Save.new(@file).load
      sleep(3) unless $debug
      self.end
    end
  end
  def draw
    @font.draw(@levelName, 320.1-((@font.text_width(@levelName)/2).round), 380.1, ZOrder::Text, 1.0, 1.0, 0xffffff00)
    @font2.draw("Loading...", 320.1-((@font2.text_width("Loading...")/2).round), 380.1+@font.height+5, ZOrder::Text, 1.0, 1.0, 0xffffff00)
  end
  def onEnd
    $window.cursor.unforceVisible
    $window.cursor.visible=false
  end
  def onTerminate
    FadeScreen.new.start
    $window.cursor.unforceVisible
    $window.cursor.visible=false
  end
end

end #module Menu

include Menu